package org.raymond.iworks.study.netty.official.fundamental.echo;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

/**
 * @author raymond
 * @version V1.0
 * @Description: Handler implementation for the echo server.
 */
@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    /**
     * A ChannelHandlerContext object provides various operations that enable you to trigger various I/O events and operations.
     * Here, we invoke write(Object) to write the received message in verbatim.
     * Please note that we did not release the received message unlike we did in the DISCARD example.
     * It is because Netty releases it for you when it is written out to the wire.
     *
     * ChannelHandlerContext实例提供了很多操作可以让你触发一些I/O相关的事件和操作.此处,我们调用write()方法将收到的数据逐字逐句的
     * 写入到网络I/O.注意我们在这里没有释放收到的消息,这一点和DISCARD例子有所不同,因为Netty会在write操作完成后自动释放相关的消息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ctx.write(msg);
        // ctx.write(Object) does not make the message written out to the wire.
        // It is buffered internally and then flushed out to the wire by ctx.flush().
        // Alternatively, you could call ctx.writeAndFlush(msg) for brevity.

        // ctx.write()并不会立即完成,而是被缓存起来:当你调用ctx.flush()方法时消息才会被发送.
        // 另外,你也可以调用ctx.writeAndFlush(msg)方法一次性完成上面两个步骤。
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// Close the connection when an exception is raised.
        cause.printStackTrace();
        ctx.close();
    }
}
